package cn.lili.modules.payment.serviceimpl;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.modules.kit.core.PaymentHttpResponse;
import cn.lili.modules.kit.core.enums.RequestMethodEnums;
import cn.lili.modules.kit.plugin.wechat.WechatApi;
import cn.lili.modules.payment.entity.dto.BankData;
import cn.lili.modules.payment.entity.dto.Branches;
import cn.lili.modules.payment.entity.dto.Cities;
import cn.lili.modules.payment.entity.dto.Provinces;
import cn.lili.modules.payment.service.WechatBankService;
import cn.lili.modules.payment.wechat.enums.WechatDomain;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 对公银行 业务实现
 *
 * @author Chopper
 * @since 2020-12-19 09:25
 */
@Slf4j
@Component
public class WechatBankServiceImpl implements WechatBankService {


    @Autowired
    private SettingClient settingClient;

    @Autowired
    private Cache cache;

    @Override
    public List<BankData> corporateBankList() {


        if (cache.hasKey(CachePrefix.WECHAT_BANK_CORPORATE.getPrefix())) {
            return (List<BankData>) cache.get(CachePrefix.WECHAT_BANK_CORPORATE.getPrefix());
        }
        List<BankData> bankData = new ArrayList<>();
        Integer offset = 0;
        while (true) {
            String url = String.format("/v3/capital/capitallhh/banks/corporate-banking?offset=%s&limit=%s", offset, 200);

            PaymentHttpResponse response = response(url);
            JSONObject jsonObject = JSONUtil.parseObj(response.getBody());

            if (jsonObject.get("count") != null && Convert.toInt(jsonObject.get("count")) > 0) {

                List<BankData> corporateBankingData = jsonObject.getBeanList("data", BankData.class);
                bankData.addAll(corporateBankingData);
            }
            if (Convert.toInt(jsonObject.get("total_count")) <= offset + 200) {
                break;
            } else {
                offset += 200;
            }
        }

        cache.put(CachePrefix.WECHAT_BANK_CORPORATE.getPrefix(), bankData, 60 * 60 * 24 * 31L);
        return bankData;
    }

    public List<BankData> personalBankList() {
        if (cache.hasKey(CachePrefix.WECHAT_BANK_PERSONAL.getPrefix())) {
            return (List<BankData>) cache.get(CachePrefix.WECHAT_BANK_PERSONAL.getPrefix());
        }
        List<BankData> bankData = new ArrayList<>();
        Integer offset = 0;
        while (true) {
            String url = String.format("/v3/capital/capitallhh/banks/personal-banking?offset=%s&limit=%s", offset, 200);
            PaymentHttpResponse response = response(url);
            JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
            if (jsonObject.get("count") != null && Convert.toInt(jsonObject.get("count")) > 0) {
                List<BankData> corporateBankingData = jsonObject.getBeanList("data", BankData.class);
                bankData.addAll(corporateBankingData);
            }
            if (Convert.toInt(jsonObject.get("total_count")) <= offset + 200) {
                break;
            } else {
                offset += 200;
            }
        }
        cache.put(CachePrefix.WECHAT_BANK_PERSONAL.getPrefix(), bankData, 60 * 60 * 24 * 31L);
        return bankData;
    }


    /**
     * 获取省市县规则
     *
     * @return 支行信息
     */
    public List<Provinces> getProvinces() {

        if (cache.hasKey(CachePrefix.WECHAT_BANK_PROVINCES.getPrefix())) {
            return (List<Provinces>) cache.get(CachePrefix.WECHAT_BANK_PROVINCES.getPrefix());
        }
        //获取省份列表
        String provincesUrl = String.format("/v3/capital/capitallhh/areas/provinces");
        PaymentHttpResponse response = response(provincesUrl);
        List<Provinces> provincesList = JSONUtil.parseObj(response.getBody())
                .getBeanList("data", Provinces.class);

        for (Provinces provinces : provincesList) {
            getCitys(provinces);
        }
        cache.put(CachePrefix.WECHAT_BANK_PROVINCES.getPrefix(), provincesList, 60 * 60 * 24 * 31L);
        return provincesList;

    }

    /**
     * 获取二级城市
     *
     * @param provinces 省份
     */
    public void getCitys(Provinces provinces) {
        String url = String.format("/v3/capital/capitallhh/areas/provinces/%s/cities", provinces.getProvince_code());
        PaymentHttpResponse citiesResponse = response(url);
        JSONObject jsonObject = JSONUtil.parseObj(citiesResponse.getBody());
        List<Cities> citiesList = jsonObject.getBeanList("data", Cities.class);
        provinces.setCitiesList(citiesList);
    }


    public List<Branches> branches(String bankAliasCode, String cityCode) {
        //支行列表
        List<Branches> branchesList = new ArrayList<>();

        Integer offset = 0;
        while (true) {
            String branchesUrl = String.format("/v3/capital/capitallhh/banks/%s/branches?city_code=%s&offset=%s&limit=%s", bankAliasCode, cityCode, offset, 200);
            PaymentHttpResponse response = response(branchesUrl);
            JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
            if (jsonObject.get("count") != null && Convert.toInt(jsonObject.get("count")) > 0) {
                branchesList.addAll(jsonObject.getBeanList("data", Branches.class));
            }
            if (Convert.toInt(jsonObject.get("total_count")) <= offset + 200) {
                break;
            } else {
                offset += 200;
            }
        }
        return branchesList;
    }


    /**
     * 获取微信支付配置
     *
     * @return
     */
    private WechatPaymentSetting wechatPaymentSetting() {
        try {
            Setting systemSetting = settingClient.get(SettingEnum.WECHAT_PAYMENT.name());
            //System.out.println(systemSetting);
            WechatPaymentSetting wechatPaymentSetting = JSONUtil.toBean(systemSetting.getSettingValue(), WechatPaymentSetting.class);
            return wechatPaymentSetting;
        } catch (Exception e) {
            log.error("微信支付暂不支持", e);
            throw new ServiceException(ResultCode.PAY_NOT_SUPPORT);
        }
    }


    private PaymentHttpResponse response(String url) {
        try {
            WechatPaymentSetting setting = wechatPaymentSetting();
            PaymentHttpResponse response = WechatApi.v3(
                    RequestMethodEnums.GET,
                    WechatDomain.CHINA.toString(),
                    url,
                    setting.getMchId(),
                    setting.getSerialNumber(),
                    null,
                    setting.getApiclient_key(),
                    ""
            );
            return response;
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return null;
    }
}